package spring.cloud.eurekaclientfund.controller;

import com.spring.cloud.commonutils.vo.UserInfo;
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.github.resilience4j.ratelimiter.RateLimiter;
import io.github.resilience4j.ratelimiter.RateLimiterRegistry;
import io.vavr.control.Try;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import spring.cloud.eurekaclientfund.service.UserFacade;

import java.util.concurrent.Callable;

@RestController
@RequestMapping("/r4j")
public class R4jUserController {

    @Autowired
    private CircuitBreakerRegistry circuitBreakerRegistry;

    @Autowired
    private RateLimiterRegistry rateLimiterRegistry;

    @Autowired
    private UserFacade userFacade;


    @GetMapping("/user/{id}")
    public UserInfo getUser(@PathVariable("id") Long id){
        //获取断路器
        CircuitBreaker circuitBreaker = circuitBreakerRegistry.circuitBreaker("user");
        //具体事件
        Callable<UserInfo> call = () ->userFacade.getUser(id);
        //断路器帮定事件
        Callable<UserInfo> call1 = CircuitBreaker.decorateCallable(circuitBreaker,call);
        //获取限速器
        RateLimiter rateLimiter = rateLimiterRegistry.rateLimiter("user");
        //限速器绑定断路器事件
        Callable<UserInfo> call2 = RateLimiter.decorateCallable(rateLimiter,call1);
        //尝试获取结果
        Try<UserInfo> result = Try.of(()->call2.call())
                //降级方法
                .recover(ex->{
                            System.out.println("异常进行降级");
                            return new UserInfo(Long.MAX_VALUE,"",ex.getMessage());
                        });

        return result.get();
    }
}
